package com.basic.boot.web.service;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

/**
 * @author cherrish
 * @time 2019-04-02 9:43
 * @name FileService
 * @desc:
 */
@Service
public class FileService {
    // 通过 Spring4 的 Value注解，获取配置文件中的属性值
    /**
     * ftp 服务器ip地址
     */
    @Value("${ftp_address}")
    private String ftpAddress;

    /**
     * ftp 服务器port，默认是21
     */
    @Value("${ftp_port}")
    private String ftpPort;

    /**
     * ftp 服务器用户名
     */
    @Value("${ftp_username}")
    private String ftpUsername;

    /**
     * ftp 服务器密码
     */
    @Value("${ftp_password}")
    private String ftpPassword;

    /**
     * ftp 服务器存储图片的绝对路径
     */
    @Value("${ftp_base_path}")
    private String ftpBasePath;

    /**
     * ftp 服务器外网访问图片路径
     */
    @Value("${image_base_url}")
    private String imageBaseUrl;

    public Map uploadPicture(MultipartFile uploadFile) {
        Map resultMap = new HashMap<>();
        try {
            // 1. 取原始文件名
            String oldName = uploadFile.getOriginalFilename();

            // 2. ftp 服务器的文件名
            String newName = oldName;
            //图片上传
            boolean result = uploadFile(ftpAddress, Integer.parseInt(ftpPort), ftpUsername, ftpPassword,
                    uploadFile.getInputStream(), ftpBasePath, newName);
            //返回结果
            if(!result) {
                resultMap.put("error", 1);
                resultMap.put("message", "upload Fail");
                return resultMap;
            }
            resultMap.put("error", 0);
            resultMap.put("url", imageBaseUrl + "/" + newName);
            return resultMap;

        } catch (Exception e) {
            e.printStackTrace();
            resultMap.put("error", 1);
            resultMap.put("message", "upload Fail");
            return resultMap;
        }
    }


    /**
     * ftp 上传图片方法
     * @param ip            ftp 服务器ip地址
     * @param port          ftp 服务器port，默认是21
     * @param account       ftp 服务器用户名
     * @param passwd        ftp 服务器密码
     * @param inputStream   文件流
     * @param workingDir    ftp 服务器存储图片的绝对路径
     * @param fileName      上传到ftp 服务器文件名
     * @throws Exception
     *
     */
    public boolean uploadFile(String ip, Integer port, String account, String passwd,
                              InputStream inputStream, String workingDir, String fileName) throws Exception{
        boolean result = false;
        // 1. 创建一个FtpClient对象
        FTPClient ftpClient = new FTPClient();
        try {
            // 2. 创建 ftp 连接
            ftpClient.connect(ip, port);
            // 3. 登录 ftp 服务器
            ftpClient.login(account, passwd);
            // 获取连接ftp 状态返回值
            int reply = ftpClient.getReplyCode();
            System.out.println("code : " + reply);
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftpClient.disconnect(); // 如果返回状态不再 200 ~ 300 则认为连接失败
                return result;
            }
            // 4. 读取本地文件
//          FileInputStream inputStream = new FileInputStream(new File("F:\\hello.png"));
            // 5. 设置上传的路径
            ftpClient.changeWorkingDirectory(workingDir);
            // 6. 修改上传文件的格式为二进制
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
            // 7. 服务器存储文件，第一个参数是存储在服务器的文件名，第二个参数是文件流
            if (!ftpClient.storeFile(fileName, inputStream)) {
                return result;
            }
            // 8. 关闭连接
            inputStream.close();
            ftpClient.logout();
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if (ftpClient.isConnected()) {
                try {
                    ftpClient.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        return result;
    }

}
